<?php
/**
 * A simple description for this script
 *
 * PHP Version 5.2.0 or Upper version
 *
 * @package    Iris
 * @author     Hidehito NOZAWA aka Suin <http://suin.asia>
 * @copyright  2010 Hidehito NOZAWA
 * @license    http://www.gnu.org/licenses/gpl-2.0.html GNU GPL v2
 *
 */

abstract class Iris_Abstract_ModelHandler
{
	protected $object  = '';
	protected $table   = '';
	protected $primary = 'id';

	protected $db      = null;

	protected $errors = array();

	public function __construct()
	{
		$this->db =& Iris::database();
		$this->table = $this->db->prefix(Iris::$dirname.'_'.$this->table);
	}

	public function create()
	{
		$obj = $this->object;
		$obj = new $obj();
		$obj->setNew();
		return $obj;
	}

	public function load($id = null)
	{
		$id = intval($id);

		$obj = $this->create();

		if ( $id > 0 )
		{
			$sql = "select * from `%s` where `%s`='%u'";
			$sql = sprintf($sql, $this->table, $this->primary, $id);
			$rsrc = $this->_query($sql, 1);
			$vars = $this->db->fetchArray($rsrc);

			$obj->unsetNew();
			$obj->setVars($vars);
		}

		return $obj;
	}

	public function save(&$obj)
	{
		if ( $obj->isNew() )
		{
			$this->_insert($obj);
		}
		else
		{
			$this->_update($obj);
		}

		return ( count($this->errors) === 0 );
	}

	public function delete($id)
	{
		$id = (int) $id;
		$sql = "DELETE FROM `%s` WHERE `%s` = '%u'";
		$sql = sprintf($sql, $this->table, $this->primary, $id);
		return $this->_query($sql);
	}

	public function count($criteria = null)
	{
		$where = '';

		if ( is_object($criteria) and is_a($criteria, 'Iris_Class_Criteria') )
		{
			$where = $criteria->render();
		}

		$sql = "SELECT COUNT(*) FROM `%s`";
		$sql = sprintf($sql, $this->table);

		if ( $where !== '' )
		{
			$sql .= ' WHERE '.$where;
		}

		$result = $this->_query($sql);
		list($total) = $this->db->fetchRow($result);
		return $total;
	}

	public function find($criteria = null, $orderby = null, $sort = 'ASC', $limit = 0, $start = 0)
	{
		$where = '';

		if ( is_object($criteria) and is_a($criteria, 'Iris_Class_Criteria') )
		{
			$where = $criteria->render();
		}

		if ( $orderby === null )
		{
			$orderby = $this->primary;
		}

		if ( !in_array($sort, array('ASC', 'DESC')) )
		{
			$sort = 'ASC';
		}

		$limit = intval($limit);
		$start = intval($start);

		$sql = 'SELECT * FROM `'.$this->table.'`';

		if ( $where !== '' )
		{
			$sql .= ' WHERE '.$where;
		}

		$sql .= ' ORDER BY `'.$orderby.'` '.$sort;

		$result = $this->_query($sql, $limit, $start);

		$models = array();

		while ( $row = $this->db->fetchArray($result) )
		{
			$model = $this->create();
			$model->unsetNew();
			$model->setVars($row);
			$models[] = $model;
		}

		if ( $limit === 1 and count($models) > 0 )
		{
			return reset($models);
		}
		else
		{
			return $models;
		}
	}


	public function getErrors()
	{
		return $this->errors;
	}

	protected function _insert(&$obj)
	{
		$vars = $obj->getVarsSqlEscaped();
		unset($vars[$this->primary]);
		$data = $this->_buildData($vars);

		$sql = "INSERT INTO `%s` SET %s";
		$sql = sprintf($sql, $this->table, $data);

		if ( !$this->_query($sql) ) return;

		$newId = $this->db->getInsertId();
		$obj->setVar($this->primary, $newId);
		$obj->unsetNew();
	}

	protected function _update(&$obj)
	{
		$id   = $obj->getVar($this->primary);
		$vars = $obj->getVarsSqlEscaped();
		$data = $this->_buildData($vars);

		$sql = "UPDATE `%s` SET %s WHERE `%s` = '%u'";
		$sql = sprintf($sql, $this->table, $data, $this->primary, $id);

		$this->_query($sql);
	}

	protected function _query($sql, $limit = null, $start = null)
	{
		$result = $this->db->queryF($sql, $limit, $start);
		if ( !$result ) $this->errors[] = $this->db->error();
		return $result;
	}

	protected function _buildData($vars)
	{
		$ret = array();

		foreach ( $vars as $name => $value )
		{
			$ret[] = sprintf("`%s` = '%s'", $name, $value);
		}

		$ret = implode(', ', $ret);

		return $ret;
	}
}

?>
